import 'package:flutter/services.dart';

final whitelistingDigitDot =
    FilteringTextInputFormatter.allow(RegExp(r'[\d.]+'));

///限制输入中文英文数字和符号
final whitelistingPassword =
    FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9~!@#$%^&*-_+=:;,.?]'));

///限制输入中文英文数字和符号
final chineseLetterDigitSymbol = FilteringTextInputFormatter.allow(
  RegExp(
      r'[\u4e00-\u9fa5]|\w|[·~！@#￥%……&*（）-；：‘”，《。》、？=+【「】」、|]|[ `~!@#$%^&*()-_=+\[\]\\{}|;:",<.>/?'
      r"']"),
);

class InputNumberConstraints extends TextInputFormatter {
  late int _beforeDotCount; //整数位
  late int _afterDotCount;
  num? _maxValue;
  num? _minValue;

  InputNumberConstraints(
    int beforeDotCount,
    int afterDotCount, {
    num? maxValue,
    num? minValue,
  }) {
    this._beforeDotCount = beforeDotCount;
    this._afterDotCount = afterDotCount;
    this._maxValue = maxValue;
    this._minValue = minValue;
  }

  @override
  TextEditingValue formatEditUpdate(
      TextEditingValue oldValue, TextEditingValue newValue) {
    String oldStr = oldValue.text;
    String newStr = newValue.text;
    int selectionIndex = newValue.selection.extentOffset;

    bool pressBack = oldStr.length > newStr.length;
    bool containsDot = oldStr.contains(".");
    String? input = selectionIndex > 0
        ? newStr.substring(selectionIndex - 1, selectionIndex)
        : null;
    int decimal = containsDot && !pressBack ? newStr.split('.')[1].length : 0;
    int maxLength = containsDot
        ? _beforeDotCount + 1 + _afterDotCount
        : _beforeDotCount + (input == '.' ? 1 : 0);

    if (newStr == ".") {
      newStr = "0.";
      selectionIndex++;
    } else if ((!pressBack && containsDot && input == '.') ||
        decimal > _afterDotCount ||
        (oldStr == '0' && input == '0') ||
        newStr.length > maxLength) {
      newStr = oldStr;
      selectionIndex = oldValue.selection.extentOffset;
    }
    if (newStr.length != 0 &&
        _maxValue != null &&
        num.parse(newStr) > _maxValue!) {
      newStr = oldStr;
      selectionIndex = oldValue.selection.extentOffset;
    }
    if (newStr.length != 0 &&
        _minValue != null &&
        num.parse(newStr) < _minValue!) {
      newStr = oldStr;
      selectionIndex = oldValue.selection.extentOffset;
    }
    return new TextEditingValue(
      text: newStr,
      selection: new TextSelection.collapsed(offset: selectionIndex),
    );
  }
}
